#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include <libgen.h>

ssize_t	writen(int fd, const void *vptr, size_t n);
void handle_signal(int s);
void InitSignal(void);


ssize_t	
writen(int fd, const void *vptr, size_t n)
{
	size_t		nleft;
	ssize_t		nwritten;
	const char	*ptr;

	ptr = vptr;
	nleft = n;
	while (nleft > 0) {
		if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
			if (errno == EINTR)
				nwritten = 0;		/* and call write() again */
			else
				return(-1);			/* error */
		}

		nleft -= nwritten;
		ptr   += nwritten;
	}
	return(n);
}

void 
handle_signal(int s) 
{ 
    //printf("%d,broken pipe!!!!\n", s);
    //usleep(1000);
    InitSignal();
}

void 
InitSignal(void)
{
    //printf("init singal\n");
    signal(SIGPIPE,handle_signal);
}


/* do nothing with the signal and reset the signal option */


int
main(int argc, char **argv)
{
	int					sockfd, n;
	struct sockaddr_in	servaddr;
	char				recvline[1024];
	
	long i = 0;
	int j;
	long interval;
	int flags;
	char arg1buf[256];
	char pathbuf[256];
	
	DIR* dir;
	struct dirent *fileList;
	FILE *handler;
	FILE *handler1;
	struct stat st;
	size_t content_length;
	long read_objects = 0;
    long write_objects = 0;
    double progress;
    long write_count = 0;
    char *ppppp;
	
	char content[8192];
	char buf[524288];
	
	char file_name[256];
	
	char enrity1_buf[8192];
	
	char enrity1[]="-----------------------------7d81d41570520\r\n"
"Content-Disposition: form-data; name=\"key\"\r\n"
"\r\n"
"%s\r\n"
"-----------------------------7d81d41570520\r\n"
"Content-Disposition: form-data; name=\"acl\"\r\n"
"\r\n"
"public-read\r\n"
"-----------------------------7d81d41570520\r\n"
"Content-Disposition: form-data; name=\"success_action_redirect\"\r\n"
"\r\n"
"http://post.test.sina.com.cn/ok.html\r\n"
"-----------------------------7d81d41570520\r\n"
"Content-Disposition: form-data; name=\"Content-Type\"\r\n"
"\r\n"
"image/jpeg\r\n"
"-----------------------------7d81d41570520\r\n"
"Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n"
"\r\n"
"1\r\n"
"-----------------------------7d81d41570520\r\n"
"Content-Disposition: form-data; name=\"Policy\"\r\n"
"\r\n"
"eyJleHBpcmF0aW9uIjogIjIwMDktMDEtMDFUMDA6MDA6MDBaIiwgImNvbmRpdGlvbnMiOiBbIHsiYWNsIjogInB1YmxpYy1yZWFkIiB9LCB7ImJ1Y2tldCI6ICJjbl9zaW5hX2RwX3Rlc3QiIH0sIFsic3RhcnRzLXdpdGgiLCAiJGtleSIsICJ0ZXN0LyJdLCB7InN1Y2Nlc3NfYWN0aW9uX3JlZGlyZWN0IjogImh0dHA6Ly9vay5jb20ifSwgWyJzdGFydHMtd2l0aCIsICIkQ29udGVudC1UeXBlIiwgImltYWdlLyJdLF0gfQ==\r\n"
"-----------------------------7d81d41570520\r\n"
"Content-Disposition: form-data; name=\"Signature\"\r\n"
"\r\n"
"/86+pK2k/u/cVdNDFxRc1WEvj7g=\r\n"
"-----------------------------7d81d41570520\r\n"
"Content-Disposition: form-data; name=\"file\"; filename=\"E:\pic\DSC05891.JPG\"\r\n"
"Content-Type: image/pjpeg\r\n\r\n";

    char enrity2[]="\r\n-----------------------------7d81d41570520\r\n"
"Content-Disposition: form-data; name=\"submit\"\r\n"
"\r\n"
"UploadtoAmazonS3\r\n"
"-----------------------------7d81d41570520--";
	
	char http_request[8192] = ""
"POST / HTTP/1.1\r\n"
"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*\r\n"
"Referer: http://post.test.sina.com.cn/x.html\r\n"
"Accept-Language: zh-cn\r\n"
"Content-Type: multipart/form-data; boundary=---------------------------7d81d41570520\r\n"
"Accept-Encoding: gzip, deflate\r\n"
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)\r\n"
"Host: test.s3.amazonaws.com\r\n"
"Connection: Keep-Alive\r\n"
"Cache-Control: no-cache\r\n"
;

    
    if (argc == 1)
    {
        printf("Usage: ./test path [interval]\n");
        printf("path: path which file to be sent.\n");
        printf("[interval]: request time interval. default 0 us.\n");
        exit(0);
    }
    
    if (argv[1] == NULL)
	{
	    printf("shit...invalid parameter!!!!\n");
	    exit(0);
	}
    
    InitSignal();
    
    memset(arg1buf, '\0', 256);
    if (argv[3] == NULL)
    {
        memcpy(arg1buf, "0", 1);
    }
    else
    {
        memcpy(arg1buf, argv[3], strlen(argv[3]));
    }
    
    interval = atol(arg1buf);
    
	printf("arg string: \t%s\n", arg1buf);
	printf("arg int: \t%ld\n", interval);
	
	
	
	for (;;)
	{
	    handler = fopen(argv[1], "rb");
	    
	    while((ppppp = fgets(pathbuf, 256, handler)) != NULL)
	    {
	        
	        write_count = 0;
	        
	        memset(content, '\0', 8192);
	        memset(enrity1_buf, '\0', 8192);
	        memset(file_name, '\0', 256);
	        
	        //memcpy(pathbuf, argv[1], 256);
	       
	        /* open the file */
	        //strncat(pathbuf, fileList->d_name, 256);
	        
	        pathbuf[strlen(pathbuf)-1]='\0';
	        handler1 = fopen(ppppp, "rb");
            
            if (handler1 == NULL)
            {
                printf("can not open file. '%s'\n", ppppp);
                continue;
            }
            
            memcpy(file_name, ppppp, strlen(ppppp));
            snprintf(enrity1_buf, 8192, enrity1, basename(file_name));
            
            /* get file size */
	        if (fstat(fileno(handler1), &st) >= 0)
            {
                content_length = st.st_size +strlen(enrity1_buf)+strlen(enrity2);
                snprintf(content, 8192, "%sContent-Length: %ld\r\n\r\n", http_request, content_length);

                printf("[%ld] %s (%ld)\n", i, ppppp, content_length);
            }
            else
            {
                printf("can not get file size. %s\n", pathbuf);
                continue;
            }
	        
	        
	        sockfd = socket(AF_INET, SOCK_STREAM, 0);

            bzero(&servaddr, sizeof(servaddr));
            servaddr.sin_family      = AF_INET;
            servaddr.sin_addr.s_addr = inet_addr(argv[2]);
            servaddr.sin_port        = htons(80);	
	    
	        if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
	        {
		        close(sockfd);
		        printf("can not connect to server. retry after 1 sec.\n");
		        sleep(1);
		        continue;
            }

            /* write header */
            writen(sockfd, content, strlen(content));
            
            /* http����ǰ�벿��*/
            writen(sockfd, enrity1_buf, strlen(enrity1_buf));
            
            /* write entity */
            while (feof(handler1) == 0)
            {
                read_objects = fread(buf, 1, 524288, handler1);
                if (read_objects < 0) 
		{printf("@read!!!!!!%d\n", read_objects);continue;}
                write_objects = write(sockfd, buf, read_objects);
                if (write_objects < 0)
		{printf("@write!!!!!%d\n", read_objects);continue;}
                write_count += write_objects;
                
                //printf(" %2.0f%%", ((float)write_count/(float)content_length)*100.0);
            }

            /* http����ǰ�벿��*/
            writen(sockfd, enrity2, strlen(enrity2));
            
            //printf("%s",content);
		memset(recvline, 0, 1024);
	        n = read(sockfd, recvline, 1024);
	        printf("%s\n",recvline);
	        
	        /* interval */
	        if (interval != 0)usleep(interval);
	
	        fclose(handler1);

            i++;
	        //if ( i == 10)exit(0);
	        
	            
            if (i % 1000 == 0)
            {
                printf("%d\n", i);
		    }
		    memset(pathbuf, '\0', 256);

            close(sockfd);
        
        }
        
        fclose(handler);
    }
}
